import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatTabsModule } from '@angular/material/tabs';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatIconModule } from '@angular/material/icon';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatSnackBarModule, MatSnackBar } from '@angular/material/snack-bar';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { 
  Observable, 
  Subject, 
  BehaviorSubject, 
  interval, 
  timer, 
  fromEvent, 
  of, 
  from, 
  combineLatest, 
  merge, 
  forkJoin,
  debounceTime, 
  distinctUntilChanged, 
  switchMap, 
  map, 
  filter, 
  take, 
  takeUntil,
  startWith,
  scan,
  tap,
  catchError,
  retry,
  delay
} from 'rxjs';

/**
 * RxJS 指南组件
 * 展示 RxJS 的各种操作符和实际应用场景
 */
@Component({
  selector: 'cne-rxjs-guide',
  standalone: true,
  imports: [
    CommonModule,
    MatButtonModule,
    MatCardModule,
    MatTabsModule,
    MatFormFieldModule,
    MatInputModule,
    MatIconModule,
    MatProgressBarModule,
    MatSnackBarModule,
    ReactiveFormsModule
  ],
  templateUrl: './rxjs-guide.component.html',
  styleUrl: './rxjs-guide.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class RxjsGuideComponent implements OnInit, OnDestroy {
  
  // 表单控件
  searchControl = new FormControl('');
  counterControl = new FormControl(0);
  
  // 数据流
  private destroy$ = new Subject<void>();
  
  // 计数器相关
  counter$ = new BehaviorSubject<number>(0);
  isCounting$ = new BehaviorSubject<boolean>(false);
  
  // 搜索相关
  searchResults$ = new BehaviorSubject<string[]>([]);
  searchTerm$ = new BehaviorSubject<string>('');
  
  // 网络请求模拟
  isLoading$ = new BehaviorSubject<boolean>(false);
  apiData$ = new BehaviorSubject<any[]>([]);
  
  // 定时器相关
  timer$ = new BehaviorSubject<number>(0);
  interval$ = new BehaviorSubject<number>(0);
  
  // 代码示例
  codeExamples = {
    // 基础操作符
    basicOperators: `// map 操作符
const numbers$ = of(1, 2, 3, 4, 5);
const doubled$ = numbers$.pipe(
  map(x => x * 2)
);
doubled$.subscribe(value => console.log(value)); // 2, 4, 6, 8, 10

// filter 操作符
const evenNumbers$ = numbers$.pipe(
  filter(x => x % 2 === 0)
);
evenNumbers$.subscribe(value => console.log(value)); // 2, 4`,

    // 组合操作符
    combinationOperators: `// combineLatest
const name$ = new BehaviorSubject('张三');
const age$ = new BehaviorSubject(25);
const user$ = combineLatest([name$, age$]).pipe(
  map(([name, age]) => ({{ '{' }} name, age {{ '}' }}))
);

// merge
const stream1$ = interval(1000).pipe(map(x => 'Stream1: ' + x));
const stream2$ = interval(1500).pipe(map(x => 'Stream2: ' + x));
const merged$ = merge(stream1$, stream2$);

// forkJoin
const api1$ = this.http.get('/api/users');
const api2$ = this.http.get('/api/posts');
const combined$ = forkJoin([api1$, api2$]);`,

    // 高级操作符
    advancedOperators: `// debounceTime - 防抖
this.searchControl.valueChanges.pipe(
  debounceTime(300),
  distinctUntilChanged(),
  switchMap(term => this.searchService.search(term))
).subscribe(results => this.searchResults$.next(results));

// retry - 重试
this.http.get('/api/data').pipe(
  retry(3),
  catchError(error => of([]))
).subscribe(data => console.log(data));

// scan - 累积
const clicks$ = fromEvent(document, 'click');
const clickCount$ = clicks$.pipe(
  map(() => 1),
  scan((acc, curr) => acc + curr, 0)
);`,

    // 实际应用场景
    realWorldExamples: `// 自动保存
this.form.valueChanges.pipe(
  debounceTime(1000),
  distinctUntilChanged(),
  switchMap(formData => this.saveService.save(formData))
).subscribe();

// 实时搜索
this.searchInput.valueChanges.pipe(
  debounceTime(300),
  distinctUntilChanged(),
  switchMap(term => 
    term ? this.searchService.search(term) : of([])
  ),
  catchError(error => {{ '{' }}
    console.error('搜索失败:', error);
    return of([]);
  {{ '}' }})
).subscribe(results => this.results = results);

// 轮询数据
interval(5000).pipe(
  switchMap(() => this.dataService.getLatestData()),
  takeUntil(this.destroy$)
).subscribe(data => this.updateData(data));`
  };

  constructor(private snackBar: MatSnackBar) {}

  ngOnInit(): void {
    this.setupSearchDemo();
    this.setupCounterDemo();
    this.setupApiDemo();
    this.setupTimerDemo();
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  /**
   * 设置搜索演示
   */
  private setupSearchDemo(): void {
    this.searchControl.valueChanges.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      tap(term => this.searchTerm$.next(term || '')),
      switchMap(term => {
        if (!term) return of([]);
        // 模拟搜索延迟
        return of(this.getMockSearchResults(term)).pipe(delay(500));
      }),
      takeUntil(this.destroy$)
    ).subscribe(results => {
      this.searchResults$.next(results);
    });
  }

  /**
   * 设置计数器演示
   */
  private setupCounterDemo(): void {
    // 监听计数器变化
    this.counterControl.valueChanges.pipe(
      takeUntil(this.destroy$)
    ).subscribe(value => {
      if (value !== null) {
        this.counter$.next(value);
      }
    });
  }

  /**
   * 设置 API 演示
   */
  private setupApiDemo(): void {
    // 模拟 API 调用
    this.isLoading$.pipe(
      filter(loading => loading),
      switchMap(() => this.simulateApiCall()),
      takeUntil(this.destroy$)
    ).subscribe(data => {
      this.apiData$.next(data);
      this.isLoading$.next(false);
    });
  }

  /**
   * 设置定时器演示
   */
  private setupTimerDemo(): void {
    // Timer 演示
    timer(0, 1000).pipe(
      take(10),
      takeUntil(this.destroy$)
    ).subscribe(value => {
      this.timer$.next(value);
    });

    // Interval 演示
    interval(2000).pipe(
      take(5),
      takeUntil(this.destroy$)
    ).subscribe(value => {
      this.interval$.next(value);
    });
  }

  /**
   * 开始计数
   */
  startCounter(): void {
    this.isCounting$.next(true);
    interval(1000).pipe(
      takeUntil(this.isCounting$.pipe(filter(counting => !counting))),
      takeUntil(this.destroy$)
    ).subscribe(() => {
      const current = this.counter$.value;
      this.counter$.next(current + 1);
      this.counterControl.setValue(current + 1);
    });
  }

  /**
   * 停止计数
   */
  stopCounter(): void {
    this.isCounting$.next(false);
  }

  /**
   * 重置计数
   */
  resetCounter(): void {
    this.counter$.next(0);
    this.counterControl.setValue(0);
    this.isCounting$.next(false);
  }

  /**
   * 模拟 API 调用
   */
  simulateApiCall(): Observable<any[]> {
    this.isLoading$.next(true);
    return of([
      { id: 1, name: '用户1', email: 'user1@example.com' },
      { id: 2, name: '用户2', email: 'user2@example.com' },
      { id: 3, name: '用户3', email: 'user3@example.com' }
    ]).pipe(
      delay(2000), // 模拟网络延迟
      tap(() => this.snackBar.open('数据加载成功！', '关闭', { duration: 2000 }))
    );
  }

  /**
   * 获取模拟搜索结果
   */
  private getMockSearchResults(term: string): string[] {
    const mockData = [
      'Angular', 'React', 'Vue', 'TypeScript', 'JavaScript',
      'RxJS', 'Node.js', 'Express', 'MongoDB', 'PostgreSQL'
    ];
    return mockData.filter(item => 
      item.toLowerCase().includes(term.toLowerCase())
    );
  }

  /**
   * 演示错误处理
   */
  demonstrateErrorHandling(): void {
    of('模拟错误').pipe(
      map(() => { throw new Error('这是一个模拟错误'); }),
      retry(2),
      catchError(error => {
        this.snackBar.open(`错误处理: ${error.message}`, '关闭', { duration: 3000 });
        return of('错误已处理');
      })
    ).subscribe(result => {
      console.log('错误处理结果:', result);
    });
  }

  /**
   * 演示组合操作符
   */
  demonstrateCombination(): void {
    const stream1$ = interval(1000).pipe(map(x => `Stream1: ${x}`), take(3));
    const stream2$ = interval(1500).pipe(map(x => `Stream2: ${x}`), take(3));
    
    merge(stream1$, stream2$).pipe(
      takeUntil(this.destroy$)
    ).subscribe(value => {
      this.snackBar.open(value, '关闭', { duration: 1000 });
    });
  }
}
